package bond

import (
	"fmt"
)

/*
可以是这四种基本类型 : int64, float64, string, Node
也可以是上面这四种类型的数组, 不支持数组嵌套.
*/
type Option struct {
	fds map[string]interface{}
}

func NewOption() *Option {
	opt := &Option{nil}
	opt.fds = make(map[string]interface{})

	/* 默认属性?? */
	return opt
}

func (opt *Option) AddField(key string, val interface{}) {
	/**/
	opt.fds[key] = val
	return
}

func (opt *Option) DelField(key string) {
	/**/
	delete(opt.fds, key)
	return
}

func (opt *Option) GetField(key string) (interface{}, error) {
	vv, ok := opt.fds[key]
	if ok {
		return vv, nil
	} else {
		return nil, fmt.Errorf("not found field %q", key)
	}
}

/* rm 是否删除这个 field */
func (opt *Option) ExpectString(key string, rm bool) (string, error) {

	/**/
	vv, err := opt.GetField(key)
	if err != nil {
		return "", err
	}

	if rm {
		opt.DelField(key)
	}

	/**/
	val, ok := vv.(string)
	if !ok {
		return "", fmt.Errorf("field %q not string", key)
	}

	return val, nil
}

/*
期望是 string 数组, 但是如果是 string 类型, 自动转换成只有一个元素的数组.
*/
func (opt *Option) ExpectStrArray(key string, rm bool) ([]string, error) {

	/**/
	vv, err := opt.GetField(key)
	if err != nil {
		return nil, err
	}

	if rm {
		opt.DelField(key)
	}

	vary, ok := vv.([]string)
	if ok {
		return vary, nil
	}

	vstr, ok := vv.(string)
	if ok {
		return []string{vstr}, nil
	}

	return nil, fmt.Errorf("field %q, type is not string", key)
}

func (opt *Option) ExpectNodeArray(key string, rm bool) ([]Node, error) {

	/**/
	vv, err := opt.GetField(key)
	if err != nil {
		return nil, err
	}

	if rm {
		opt.DelField(key)
	}

	/**/
	vary, ok := vv.([]Node)
	if ok {
		return vary, nil
	}

	/**/
	vnd, ok := vv.(Node)
	if ok {
		return []Node{vnd}, nil
	}

	/**/
	return nil, fmt.Errorf("field %q, type is not Node", key)
}
